<template>
  <div class="message-boarder-wrapper" @mousemove="handlePinMouseMove" @mouseup="handlePinMouseUp" style="height: 2000px; width: 2000px;">
    <div class="back-button-wrapper">
      <div class="back-line" />
      <div class="back-button" title="回到首页" @click="toIndexPage">
        <a-icon type="undo" class="icon"></a-icon>
      </div>
    </div>
    <span v-if="loading" style="color: black; font-size: 32px;">加载数据中...</span>
    <div id="action-bar">
      <div @click="addBoarder" class="action-button">
        <a-icon type="plus" class="icon"></a-icon>
      </div>
      <div class="action-button">
        <a-icon type="edit" class="icon"></a-icon>
      </div>
      <div class="action-button" @mouseup.capture.stop="handleClickDelete">
        <a-icon type="delete" class="icon"></a-icon>
      </div>
    </div>
    <div class="message-wrapper" 
         :class="{active: index === curIndex}"
         v-for="(boarder, index) in boarders" 
         :key="boarder.id" 
         :style="{left: boarder.left + 'px', top: boarder.top + 'px'}">
      <div class="header-wrapper" :style="{
        backgroundColor: boarder['headerBackgroundColor']
      }">
        <div class="pin" 
             @mousedown="handlePinMouseDown(index, $event)"
             :style="{backgroundColor: '#ffd17f'}"/>
      </div>
      <div class="body-wrapper" >
        <textarea 
          name="" 
          id="" 
          class="input-area" 
          v-model="boarder.content" 
          :readonly="!boarder['isMe']" 
          @change="handleTextChange(boarder)"
          :style="{
            backgroundColor: boarder['bodyBackgroundColor']
          }"
        />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "index",
  data: _ => ({
    loading: true,
    startX: 0,
    startY: 0,
    startLeft: 0,
    startTop: 0,
    isMoving: false,
    targetMsgBoard: null,
    editingHandler: null,
    curBoarder: null,
    curIndex: null,
    boarders: []
  }),
  methods: {
    toIndexPage () {
      this.$router.push('/')
    },
    async handleClickDelete () {
      if (this.curIndex) {
        this.$confirm({
          title: '确认删除',
          content: '确认删除选中的此条留言吗？',
          okText: '确认',
          cancelText: '取消',
          onOk: _ => {
            return new Promise(async (resolve, reject) => {
              try {
                let {data} = await this.$http.post(`/msgBoarder/deleteOneById?id=${this.boarders[this.curIndex].id}`)
                this.$message.success(data.msg)
                this.curIndex = null
                this.findByRect(0, 0, 2000, 2000).then(_ => {}).catch(_ => {})
                resolve()
              } catch ({data}) {
                this.$message.error(data.msg)
                reject()
              }
            })
          },
          onCancel() {},
        });
      } else {
        this.$message.info('未选择')
      }
    },
    handleClickWrapper () {
      console.log('clicked')
      this.curIndex = null
    },
    async addBoarder () {
      try {
        let {data} = await this.$http.post('/msgBoarder/insertOne')
        this.$message.success(data.msg)
        this.boarders.push(data.data)
      } catch ({data}) {
        this.$message.error(data.msg)
      }
    },
    handlePinMouseDown (i, e) {
      if (this.boarders[i].isMe) {
        this.isMoving = true
        this.targetMsgBoard = e.target.parentElement.parentElement
        this.startX = e.clientX
        this.startY = e.clientY
        this.startLeft = Number.isNaN(Number.parseInt(this.targetMsgBoard.style.left)) ? 0 : Number.parseInt(this.targetMsgBoard.style.left)
        
        this.startTop = Number.isNaN(Number.parseInt(this.targetMsgBoard.style.top)) ? 0 : Number.parseInt(this.targetMsgBoard.style.top)
        this.curBoarder = this.boarders[i]
        this.curIndex = i
      }
    },
    handlePinMouseUp (e) {
      if (this.isMoving) {
        this.isMoving = false
        if (e.clientX - this.startX !== 0 && e.clientY - this.startY !== 0) {
          this.curBoarder.left = this.startLeft + e.clientX - this.startX
          this.curBoarder.top = this.startTop + e.clientY - this.startY
          this.saveBoarder(this.curBoarder)
        } 
      } else {
        if (this.curIndex !== null) {
          this.curIndex = null
        }
      }
    },
    handlePinMouseMove (e) {
      if (this.isMoving) {
        this.targetMsgBoard.style.left = (this.startLeft + e.clientX - this.startX) + 'px'
        this.targetMsgBoard.style.top = (this.startTop + e.clientY - this.startY) + 'px'
      }
    },
    handleTextChange (boarder) {
      this.saveBoarder(boarder)
    },
    async saveBoarder (boarder) {
      boarder['createTime'] = null
      boarder['userId'] = null
      try {
        let {data} = await this.$http.post('/msgBoarder/updateOne', boarder)
        this.$message.success(data.msg)
      } catch ({data}) {
        this.$message.error(data.msg)
      }
    },
    async findByRect(offsetX, offsetY, width, height) {
      let params = new URLSearchParams()
      params.append('offsetX', offsetX)
      params.append('offsetY', offsetY)
      params.append('width', width)
      params.append('height', height)
      try {
        this.loading = true
        let {data} = await this.$http.get(`/msgBoarder?${params.toString()}`)
        this.loading = false
        this.boarders = data.data
      } catch ({data}) {
        this.$message.error(data.msg)
      }
    }
  },
  mounted() {
    this.findByRect(0, 0, 2000, 2000)
  }
}
</script>

<style scoped lang="less">
.message-boarder-wrapper {
  .back-button-wrapper {
    position: fixed;
    left: 30px;
    top: -55px;
    display: flex;
    flex-direction: column;
    justify-content: left;
    align-items: center;
    transition: .3s;
    .back-line {
      width: 1px;
      height: 30px;
      background-color: #aaaaaa;
    }
    .back-button {
      cursor: pointer;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      box-sizing: border-box;
      border: 1px solid #aaaaaa;
      display: flex;
      justify-content: center;
      align-items: center;
      transition: .3s;
      .icon {
        color: #aaaaaa;
        font-size: 32px;
        transition: .3s;
        transform: rotate(-90deg);
      }
    }
    
    &:hover {
      top: 0;
      .back-button {
        box-shadow: 3px 3px 10px 1px #aaaaaa;
        .icon {
          transform: rotate(90deg);
        }
      }
    }
  }
  
  .message-wrapper {
    position: absolute;
    box-sizing: border-box;
    border: 1px solid #eeeeee;
    width: 200px;
    transition: border .3s ease-in-out, box-shadow .3s ease-in-out;
    .header-wrapper {
      height: 20px;
      position: relative;
      .pin {
        cursor: move;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        background-color: #a3f0ff;
        border: 1px solid #2c3e50;
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        margin: 0 auto;
        transition: .3s;
      }
    }
    .body-wrapper {
      height: 100px;
      .input-area {
        width: 100%;
        height: 100%;
        outline: none;
        resize: none;
      }
    }
    
    &.active {
      border: 1px solid #1e80ff;
      box-shadow: 0 0 3px 3px #a3f0ff;
      .pin {
        box-shadow: 0 0 3px 3px #a3f0ff;
      }
    }
  }
  
  #action-bar {
    width: 50px;
    height: 50px;
    position: fixed;
    box-sizing: content-box;
    padding: 10px;
    right: 30px;
    top: 30px;
    overflow: hidden;
    transition: height .3s ease-in-out;
    z-index: 999;
    &:hover {
      height: 170px;
    }
    .action-button {
      cursor: pointer;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      border: 1px solid #eeeeee;
      box-shadow: 0 0 1px 0 #aaaaaa;
      transition: .3s;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: white;
      .icon {
        color: #aaaaaa;
        font-size: 24px;
        transition: .3s;
      }
      &:first-child {
        &:hover {
          .icon {
            transform: rotate(90deg);
          }
        }
      }
      &:not(:first-child) {
        margin-top: 10px;
      }
      &:hover {
        box-shadow: 3px 3px 10px 1px #aaaaaa;
      }
    }
  }
}
</style>